/**********************************************************************

  Audacity: A Digital Audio Editor

  RulerPanel.cpp

  Dominic Mazzoni

  Michael Papadopoulos split from Ruler.cpp

*******************************************************************//**

\class RulerPanel
\brief RulerPanel class allows you to work with a Ruler like
  any other wxWindow.

*//******************************************************************/

#include "RulerPanel.h"

#include "LinearUpdater.h"
#include "LogarithmicUpdater.h"

#include <wx/dcclient.h>

BEGIN_EVENT_TABLE(RulerPanel, wxPanelWrapper)
EVT_ERASE_BACKGROUND(RulerPanel::OnErase)
EVT_PAINT(RulerPanel::OnPaint)
EVT_SIZE(RulerPanel::OnSize)
END_EVENT_TABLE()

IMPLEMENT_CLASS(RulerPanel, wxPanelWrapper)

RulerPanel::RulerPanel(wxWindow* parent, wxWindowID id, wxOrientation orientation, const wxSize& bounds, const Range& range,
                       const RulerFormat& format, const TranslatableString& units, const Options& options,
                       const wxPoint& pos /*= wxDefaultPosition*/, const wxSize& size /*= wxDefaultSize*/
                       )
    : wxPanelWrapper(parent, id, pos, size)
    , ruler{
            [&]() -> const RulerUpdater& {
        if (options.log) {
            return LogarithmicUpdater::Instance();
        } else {
            return LinearUpdater::Instance();
        }
    }(),
            format
            }
{
    ruler.SetBounds(0, 0, bounds.x, bounds.y);
    ruler.SetOrientation(orientation);
    ruler.SetRange(range.first, range.second);
    ruler.SetUnits(units);
    ruler.SetFlip(options.flip);
    ruler.SetLabelEdges(options.labelEdges);
    ruler.mbTicksAtExtremes = options.ticksAtExtremes;
    if (orientation == wxVERTICAL) {
        wxCoord w;
        ruler.GetMaxSize(&w, NULL);
        SetMinSize(wxSize(w, 150)); // height needed for wxGTK
    } else if (orientation == wxHORIZONTAL) {
        wxCoord h;
        ruler.GetMaxSize(NULL, &h);
        SetMinSize(wxSize(wxDefaultCoord, h));
    }
    if (options.hasTickColour) {
        ruler.SetTickColour(options.tickColour);
    }
}

RulerPanel::~RulerPanel()
{
}

void RulerPanel::OnErase(wxEraseEvent& WXUNUSED(evt))
{
    // Ignore it to prevent flashing
}

void RulerPanel::OnPaint(wxPaintEvent& WXUNUSED(evt))
{
    wxPaintDC dc(this);

#if defined(__WXMSW__)
    dc.Clear();
#endif

    ruler.Draw(dc);
}

void RulerPanel::OnSize(wxSizeEvent& WXUNUSED(evt))
{
    Refresh();
}

// LL:  We're overloading DoSetSize so that we can update the ruler bounds immediately
//      instead of waiting for a wxEVT_SIZE to come through.  This is needed by (at least)
//      FrequencyPlotDialog since it needs to have an updated ruler before RulerPanel gets the
//      size event.
void RulerPanel::DoSetSize(int x, int y,
                           int width, int height,
                           int sizeFlags)
{
    wxPanelWrapper::DoSetSize(x, y, width, height, sizeFlags);

    int w, h;
    GetClientSize(&w, &h);

    ruler.SetBounds(0, 0, w - 1, h - 1);
}
